// This MFC Samples source code demonstrates using MFC Microsoft Office Fluent User Interface 
// (the "Fluent UI") and is provided only as referential material to supplement the 
// Microsoft Foundation Classes Reference and related electronic documentation 
// included with the MFC C++ library software.  
// License terms to copy, use or distribute the Fluent UI are available separately.  
// To learn more about our Fluent UI licensing program, please visit 
// http://msdn.microsoft.com/officeui.
//
// Copyright (C) Microsoft Corporation
// All rights reserved.

// ogleditorView.cpp : implementation of the CogleditorView class
//

#include "stdafx.h"
// SHARED_HANDLERS can be defined in an ATL project implementing preview, thumbnail
// and search filter handlers and allows sharing of document code with that project.
#ifndef SHARED_HANDLERS
#include "ogleditor.h"
#endif

#include "ogleditorDoc.h"
#include "ogleditorView.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#endif


// CogleditorView

IMPLEMENT_DYNCREATE(CogleditorView, CView)

BEGIN_MESSAGE_MAP(CogleditorView, CView)
	ON_WM_CONTEXTMENU()
	ON_WM_RBUTTONUP()
	ON_WM_CREATE()
	ON_WM_SIZE()
	ON_WM_DESTROY()
	ON_WM_TIMER()
	ON_WM_ERASEBKGND()
END_MESSAGE_MAP()

// CogleditorView construction/destruction

CogleditorView::CogleditorView()
	: m_pDC(NULL)
{
	// TODO: add construction code here
}

CogleditorView::~CogleditorView()
{
}

BOOL CogleditorView::PreCreateWindow(CREATESTRUCT& cs)
{
	cs.style |= WS_CLIPSIBLINGS | WS_CLIPCHILDREN;

	return CView::PreCreateWindow(cs);
}

// CogleditorView drawing

void CogleditorView::OnDraw(CDC* /*pDC*/)
{
	CogleditorDoc* pDoc = GetDocument();
	ASSERT_VALID(pDoc);
	if (!pDoc)
		return;

	// TODO: add draw code for native data here
	::glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );


	::glPushMatrix();
	// define all vertices   X     Y     Z
	GLfloat v0[3], v1[3], v2[3], v3[3], delta;
	int color = 0;

	delta = 0.5f;

	// define the two colors
	GLfloat color1[3] = { 0.9f, 0.9f, 0.9f };
	GLfloat color2[3] = { 0.05f, 0.05f, 0.05f };

	v0[1] = v1[1] = v2[1] = v3[1] = 0.0f;

	::glBegin( GL_QUADS );

	for ( int x = -5 ; x <= 5 ; x++ )
	{
		for ( int z = -5 ; z <= 5 ; z++ )
		{
			::glColor3fv( (color++)%2 ? color1 : color2 );

			v0[0] = 0.0f+delta*z;
			v0[2] = 0.0f+delta*x;

			v1[0] = v0[0]+delta;
			v1[2] = v0[2];

			v2[0] = v0[0]+delta;
			v2[2] = v0[2]+delta;

			v3[0] = v0[0];
			v3[2] = v0[2]+delta;

			::glVertex3fv( v0 );
			::glVertex3fv( v1 );
			::glVertex3fv( v2 );
			::glVertex3fv( v3 );
		}
	}
	::glEnd();	
	::glPopMatrix();


	// flush the graphics pipeline
	::glFinish();
}

void CogleditorView::OnRButtonUp(UINT /* nFlags */, CPoint point)
{
	ClientToScreen(&point);
	OnContextMenu(this, point);
}

void CogleditorView::OnContextMenu(CWnd* /* pWnd */, CPoint point)
{
#ifndef SHARED_HANDLERS
	theApp.GetContextMenuManager()->ShowPopupMenu(IDR_POPUP_EDIT, point.x, point.y, this, TRUE);
#endif
}


// CogleditorView diagnostics

#ifdef _DEBUG
void CogleditorView::AssertValid() const
{
	CView::AssertValid();
}

void CogleditorView::Dump(CDumpContext& dc) const
{
	CView::Dump(dc);
}

CogleditorDoc* CogleditorView::GetDocument() const // non-debug version is inline
{
	ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CogleditorDoc)));
	return (CogleditorDoc*)m_pDocument;
}
#endif //_DEBUG


// CogleditorView message handlers


int CogleditorView::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
	if (CView::OnCreate(lpCreateStruct) == -1)
		return -1;

	// TODO:  Add your specialized creation code here
	InitGL();

	return 0;
}


void CogleditorView::OnSize(UINT nType, int cx, int cy)
{
	CView::OnSize(nType, cx, cy);

	if (cy > 0)
	{
		glViewport(0, 0, cx, cy);

		if ((m_oldRect.right > cx) || (m_oldRect.bottom > cy))
			RedrawWindow();

		m_oldRect.right = cx;
		m_oldRect.bottom = cy;

		glMatrixMode(GL_PROJECTION);
		glLoadIdentity();
		gluPerspective(45.0f, (GLdouble)cx / cy, 3.0f, 7.0f);
		glMatrixMode(GL_MODELVIEW);

		::glMatrixMode(GL_MODELVIEW);
		::glLoadIdentity();
		::glTranslatef( 0.0f, 0.0f, -5.0f );
		::glRotatef( 20.0f, 1.0f, 0.0f, 0.0f );
	}

}


void CogleditorView::OnDestroy()
{
	CView::OnDestroy();

	// TODO: Add your message handler code here

	// this call makes the current RC not current
	if ( FALSE ==  ::wglMakeCurrent( 0, 0 ) )
	{
		::AfxMessageBox(_T("wglMakeCurrent failed."));
	}

	// delete the RC
	if ( m_hRC && (FALSE == ::wglDeleteContext( m_hRC )) )
	{
		::AfxMessageBox(_T("wglDeleteContext failed."));
	}

	// delete the DC
	if ( m_pDC )
	{
		delete m_pDC;
	}
}


void CogleditorView::OnTimer(UINT_PTR nIDEvent)
{
	// TODO: Add your message handler code here and/or call default

	CView::OnTimer(nIDEvent);
}

BOOL CogleditorView::InitGL()
{
	m_pDC = new CClientDC(this);

	if ( NULL == m_pDC ) // failure to get DC
	{
		::AfxMessageBox(_T("Couldn't get a valid DC."));
		return FALSE;
	}

	if ( !SetupPixelFormat() )
	{
		::AfxMessageBox(_T("SetupPixelFormat failed.\n"));
		return FALSE;
	}

	if ( 0 == (m_hRC = 
		::wglCreateContext( m_pDC->GetSafeHdc() ) ) )
	{
		::AfxMessageBox(_T("wglCreateContext failed."));
		return FALSE;
	}

	if ( FALSE == 
		::wglMakeCurrent( m_pDC->GetSafeHdc(), m_hRC ) )
	{
		::AfxMessageBox(_T("wglMakeCurrent failed."));
		return FALSE;
	}

	// specify black as clear color
	::glClearColor( 0.0f, 0.2f, 0.5f, 0.0f );
	// specify the back of the buffer as clear depth
	::glClearDepth( 1.0f );
	// enable depth testing
	::glEnable( GL_DEPTH_TEST );

	return TRUE;
}

BOOL CogleditorView::SetupPixelFormat(PIXELFORMATDESCRIPTOR* pPFD)
{
	// default pixel format for a single-buffered,
	// OpenGL-supporting, hardware-accelerated, 
	// RGBA-mode format. Pass in a pointer to a different
	// pixel format if you want something else
	PIXELFORMATDESCRIPTOR pfd = 
	{
		sizeof(PIXELFORMATDESCRIPTOR),// size of this pfd
		1,                      // version number
		PFD_DRAW_TO_WINDOW |    // support window
		PFD_SUPPORT_OPENGL,   // support OpenGL
		PFD_TYPE_RGBA,          // RGBA type
		24,                     // 24-bit color depth
		0, 0, 0, 0, 0, 0,       // color bits ignored
		0,                      // no alpha buffer
		0,                      // shift bit ignored
		0,                      // no accumulation buffer
		0, 0, 0, 0,             // accum bits ignored
		16,                     // 16-bit z-buffer
		0,                      // no stencil buffer
		0,                      // no auxiliary buffer
		PFD_MAIN_PLANE,         // main layer
		0,                      // reserved
		0, 0, 0                 // layer masks ignored
	};

	int pixelformat;
	PIXELFORMATDESCRIPTOR* pPFDtoUse;

	// let the user override the default pixel format
	pPFDtoUse = (0 == pPFD)? &pfd : pPFD; 

	if ( 0 == (pixelformat = 
		::ChoosePixelFormat( m_pDC->GetSafeHdc(), pPFDtoUse )) )
	{
		::AfxMessageBox(_T("ChoosePixelFormat failed."));
		return FALSE;
	}

	if ( FALSE == ::SetPixelFormat( m_pDC->GetSafeHdc(),
		pixelformat, pPFDtoUse ) )
	{
		::AfxMessageBox(_T("SetPixelFormat failed."));
		return FALSE;
	}

	return TRUE;
}


BOOL CogleditorView::OnEraseBkgnd(CDC* pDC)
{
	return TRUE;
}
